package com.utils;

import com.domain.Account;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.*;

import javax.sql.DataSource;
import java.beans.PropertyDescriptor;
import java.sql.*;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Auther: ChenJinEn
 * @Date: 2020/7/28 15:06
 * @Description: //TODO
 */
public class MyQueryRunner extends QueryRunner {
    private static  Connection con;
    private static ComboPooledDataSource c3p0 = new ComboPooledDataSource();
    private static  MyQueryRunner qr = new MyQueryRunner();
    private static  MyQueryRunner qr1 = new MyQueryRunner(c3p0);
    static {
        try {
            if (con == null) {
                con = JDBCUtil.getConnection();
                //Connection connection = c3p0.getConnection();
            }
            c3p0.setDriverClass("com.mysql.jdbc.Driver");
            c3p0.setJdbcUrl("jdbc:mysql://localhost:3306/db_cdm0menjin");
            c3p0.setUser("root");
            c3p0.setPassword("root");
            c3p0.setInitialPoolSize(10);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
    /**
     update(Connection conn, String sql, Object... params),通用增删改操作,和我们写的框架一样用
     query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
     通用查询操作,返回结果取决于ResultSetHandler<T>接口使用的子类是什么
     */

        //获取当个对象或者集合
        Account account = qr.query(con, "select * from account where id = ?", new BeanHandler<>(Account.class),1);
        System.out.println(account);
        List<Account> list = qr.query(con, "select * from account", new BeanListHandler<>(Account.class));
        list.forEach(System.out::println);
        Map<String, Object> map = qr.query(con, "select * from account where id = ?", new MapHandler(), 1);
        String json = map.toString().replace("=", ":");
        System.out.println(json);
        List<Map<String, Object>> mapList = qr.query(con, "select * from account", new MapListHandler());
        for (Map<String, Object> map1: mapList) {
            Set<Map.Entry<String, Object>> entries = map1.entrySet();
            for (Map.Entry<String, Object> entry : entries) {
                System.out.print(entry.getKey()+" "+entry.getValue()+"\t");
            }
            System.out.println();
        }
        //获取特殊单个值得演示
        Long count = qr.query(con, "select count(*) from account", new ScalarHandler<>());
        System.out.println(count);
        DbUtils.closeQuietly(con);
    }
    public MyQueryRunner() {
        super();
    }

    public MyQueryRunner(boolean pmdKnownBroken) {
        super(pmdKnownBroken);
    }

    public MyQueryRunner(DataSource ds) {
        super(ds);
    }

    public MyQueryRunner(DataSource ds, boolean pmdKnownBroken) {
        super(ds, pmdKnownBroken);
    }

    @Override
    public int[] batch(Connection conn, String sql, Object[][] params) throws SQLException {
        return super.batch(conn, sql, params);
    }

    @Override
    public int[] batch(String sql, Object[][] params) throws SQLException {
        return super.batch(sql, params);
    }

    @Override
    public <T> T query(Connection conn, String sql, Object param, ResultSetHandler<T> rsh) throws SQLException {
        return super.query(conn, sql, param, rsh);
    }

    @Override
    public <T> T query(Connection conn, String sql, Object[] params, ResultSetHandler<T> rsh) throws SQLException {
        return super.query(conn, sql, params, rsh);
    }

    @Override
    public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException {
        return super.query(conn, sql, rsh, params);
    }

    @Override
    public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh) throws SQLException {
        return super.query(conn, sql, rsh);
    }

    @Override
    public <T> T query(String sql, Object param, ResultSetHandler<T> rsh) throws SQLException {
        return super.query(sql, param, rsh);
    }

    @Override
    public <T> T query(String sql, Object[] params, ResultSetHandler<T> rsh) throws SQLException {
        return super.query(sql, params, rsh);
    }

    @Override
    public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException {
        return super.query(sql, rsh, params);
    }

    @Override
    public <T> T query(String sql, ResultSetHandler<T> rsh) throws SQLException {
        return super.query(sql, rsh);
    }

    @Override
    public int update(Connection conn, String sql) throws SQLException {
        return super.update(conn, sql);
    }

    @Override
    public int update(Connection conn, String sql, Object param) throws SQLException {
        return super.update(conn, sql, param);
    }

    @Override
    public int update(Connection conn, String sql, Object... params) throws SQLException {
        return super.update(conn, sql, params);
    }

    @Override
    public int update(String sql) throws SQLException {
        return super.update(sql);
    }

    @Override
    public int update(String sql, Object param) throws SQLException {
        return super.update(sql, param);
    }

    @Override
    public int update(String sql, Object... params) throws SQLException {
        return super.update(sql, params);
    }

    @Override
    public <T> T insert(String sql, ResultSetHandler<T> rsh) throws SQLException {
        return super.insert(sql, rsh);
    }

    @Override
    public <T> T insert(String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException {
        return super.insert(sql, rsh, params);
    }

    @Override
    public <T> T insert(Connection conn, String sql, ResultSetHandler<T> rsh) throws SQLException {
        return super.insert(conn, sql, rsh);
    }

    @Override
    public <T> T insert(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException {
        return super.insert(conn, sql, rsh, params);
    }

    @Override
    public <T> T insertBatch(String sql, ResultSetHandler<T> rsh, Object[][] params) throws SQLException {
        return super.insertBatch(sql, rsh, params);
    }

    @Override
    public <T> T insertBatch(Connection conn, String sql, ResultSetHandler<T> rsh, Object[][] params) throws SQLException {
        return super.insertBatch(conn, sql, rsh, params);
    }

    @Override
    public DataSource getDataSource() {
        return super.getDataSource();
    }

    @Override
    public boolean isPmdKnownBroken() {
        return super.isPmdKnownBroken();
    }

    @Override
    protected PreparedStatement prepareStatement(Connection conn, String sql) throws SQLException {
        return super.prepareStatement(conn, sql);
    }

    @Override
    protected PreparedStatement prepareStatement(Connection conn, String sql, int returnedKeys) throws SQLException {
        return super.prepareStatement(conn, sql, returnedKeys);
    }

    @Override
    protected Connection prepareConnection() throws SQLException {
        return super.prepareConnection();
    }

    @Override
    public void fillStatement(PreparedStatement stmt, Object... params) throws SQLException {
        super.fillStatement(stmt, params);
    }

    @Override
    public void fillStatementWithBean(PreparedStatement stmt, Object bean, PropertyDescriptor[] properties) throws SQLException {
        super.fillStatementWithBean(stmt, bean, properties);
    }

    @Override
    public void fillStatementWithBean(PreparedStatement stmt, Object bean, String... propertyNames) throws SQLException {
        super.fillStatementWithBean(stmt, bean, propertyNames);
    }

    @Override
    protected void rethrow(SQLException cause, String sql, Object... params) throws SQLException {
        super.rethrow(cause, sql, params);
    }

    @Override
    protected ResultSet wrap(ResultSet rs) {
        return super.wrap(rs);
    }

    @Override
    protected void close(Connection conn) throws SQLException {
        super.close(conn);
    }

    @Override
    protected void close(Statement stmt) throws SQLException {
        super.close(stmt);
    }

    @Override
    protected void close(ResultSet rs) throws SQLException {
        super.close(rs);
    }
}
